package com.zzy.mccjt.core.interceptor;

import com.zzy.mccjt.annotation.NoAuth;
import com.zzy.mccjt.annotation.WithAvailableTenant;
import com.zzy.mccjt.annotation.WithoutTenant;
import com.zzy.mccjt.exception.NoPermissionException;
import com.zzy.mccjt.model.CurrentTenant;
import com.zzy.mccjt.model.CurrentUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.Objects;

import static com.zzy.mccjt.constant.RequestConstant.CURRENT_USER;
import static com.zzy.mccjt.constant.RequestConstant.TENANT_CODE;
import static com.zzy.mccjt.constant.RequestConstant.TENANT_ID;
import static com.zzy.mccjt.constant.RequestConstant.TENANT_IGNORE_STATUS;
import static com.zzy.mccjt.constant.RequestConstant.TENANT_STATUS;
import static com.zzy.mccjt.constant.RequestConstant.TENANT_UNAVAILABLE_STATUS;
import static com.zzy.mccjt.constant.RequestConstant.USER_FLAG;

/**
 * @program: mccjt-cloud
 * @description:
 * @author: zhouyang.zheng
 * @create: 2022-08-02 17:39
 **/
@Slf4j
public abstract class AbstractRequestInterceptor implements HandlerInterceptor {


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        CurrentUser.clear();
        CurrentTenant.clear();
    }

    public boolean isHave(HandlerMethod handler, Class<? extends Annotation> annotation) {
        return handler.getMethodAnnotation(annotation) != null
                || (handler.getBean().getClass().getAnnotation(annotation) != null);
    }

    protected boolean isNoAuth(HttpServletRequest request, HandlerMethod handler) {
        if (isHave(handler, NoAuth.class)) {
            // 有些场景 noauth的情况下 某些接口需要带 用户信息
            String userId = request.getHeader(CURRENT_USER);
            String userFlag = request.getHeader(USER_FLAG);
            if (!StringUtils.isEmpty(userId) && !StringUtils.isEmpty(userFlag)) {
                CurrentUser.set(Integer.parseInt(userFlag), Long.parseLong(userId));
            }
            return true;
        }
        return false;
    }

    protected void handleTenantInfo(HttpServletRequest request, HandlerMethod handler) {
        String tenantStatus = request.getHeader(TENANT_STATUS);

        if (isHave(handler, WithoutTenant.class)
                || (Objects.nonNull(tenantStatus) && Integer.parseInt(tenantStatus) == TENANT_IGNORE_STATUS)) {
            return;
        }

        String tenantId = request.getHeader(TENANT_ID);
        String tenantCode = request.getHeader(TENANT_CODE);

        if (isHave(handler, WithAvailableTenant.class)
                && Objects.nonNull(tenantStatus)
                && Integer.parseInt(tenantStatus) == TENANT_UNAVAILABLE_STATUS) {
            log.warn("租户授权已过期[tenant_id: {}, tenant_code: {}, tenant_status: {}]", tenantId, tenantCode, tenantStatus);
            throw new NoPermissionException(HttpStatus.FORBIDDEN.value(), "FORBIDDEN, UNAVAILABLE_TENANT");
        }
        if (!StringUtils.isEmpty(tenantId) && !StringUtils.isEmpty(tenantCode)) {
            CurrentTenant.set(Long.valueOf(tenantId), tenantCode);
        } else {
            log.warn("租户信息不合法[tenant_id: {}, tenant_code: {}]", tenantId, tenantCode);
            throw new NoPermissionException(HttpStatus.FORBIDDEN.value(), "FORBIDDEN, INVALID_TENANT_CODE");
        }
    }
}